/**************************************************************
* Copyright (C) 2022 www.eipflow.com 孙泽伟版权所有(盗版必究)
*
* 作者: 孙泽伟(QQ 1039318332)
* 创建时间: 2018/11/9 9:21:04
* 文件名: 
* 描述: 
* 
* 修改历史
* 修改人：
* 时间：
* 修改说明：
*
**************************************************************/
using EIP.Agile.Models.Dtos.Config;
using EIP.Agile.Models.Dtos.DataBase;
using EIP.Agile.Repository;
using EIP.Base.Models.Entities.Agile;
using EIP.Base.Repository.Fixture;
using EIP.Common.Core.Context;
using EIP.Common.Extension;
using EIP.Common.Logic;
using EIP.Common.Models;
using EIP.Common.Models.Dtos;
using EIP.Common.Models.Paging;
using EIP.Common.Util;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace EIP.Agile.Logic.Impl
{
    /// <summary>
    /// 敏捷开发业务逻辑接口实现
    /// </summary>
    public class AgileConfigLogic : DapperAsyncLogic<AgileConfig>, IAgileConfigLogic
    {
        #region 构造函数
        private readonly IAgileDataBaseRepository _agileDataBaseRepository;
        private readonly IAgileConfigRepository _agileConfigRepository;

        /// <summary>
        /// 模块
        /// </summary>
        /// <param name="agileConfigRepository"></param>
        public AgileConfigLogic(IAgileConfigRepository agileConfigRepository, IAgileDataBaseRepository agileDataBaseRepository)
        {
            _agileConfigRepository = agileConfigRepository;
            _agileDataBaseRepository = agileDataBaseRepository;
        }

        #endregion

        #region 方法

        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="input">实体</param>
        /// <returns></returns>
        public async Task<OperateStatus> Save(AgileConfig input)
        {
            OperateStatus operateStatus = new OperateStatus();
            AgileConfig agileConfig = await FindAsync(f => f.ConfigId == input.ConfigId);
            var currentUser = EipHttpContext.CurrentUser();
            if (agileConfig == null)
            {
                input.CreateTime = DateTime.Now;
                input.CreateUserId = currentUser.UserId;
                input.CreateUserName = currentUser.Name;
                input.UpdateTime = DateTime.Now;
                input.UpdateUserId = currentUser.UserId;
                input.UpdateUserName = currentUser.Name;
                operateStatus = await InsertAsync(input);
            }
            else
            {
                if (input.DataFromName != agileConfig.DataFromName)
                {
                    agileConfig.SaveJson = null;
                    agileConfig.PublicJson = null;
                    agileConfig.ColumnJson = null;
                }
                agileConfig.OrderNo = input.OrderNo;
                agileConfig.Name = input.Name;
                agileConfig.DataFrom = input.DataFrom;
                agileConfig.DataFromName = input.DataFromName;
                agileConfig.IsFreeze = input.IsFreeze;
                agileConfig.Remark = input.Remark;
                agileConfig.EditConfigId = input.EditConfigId;
                agileConfig.FormCategory = input.FormCategory;
                agileConfig.FormPcUrl = input.FormPcUrl;
                agileConfig.FormMobileUrl = input.FormMobileUrl;
                agileConfig.UseType = input.UseType;
                agileConfig.TypeId = input.TypeId;

                agileConfig.UpdateTime = DateTime.Now;
                agileConfig.UpdateUserId = currentUser.UserId;
                agileConfig.UpdateUserName = currentUser.Name;

                operateStatus = await UpdateAsync(agileConfig);
            }
            if (operateStatus.Code == ResultCode.Success)
            {
                operateStatus.Msg = "保存成功";
            }
            return operateStatus;
        }

        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="input">实体</param>
        /// <returns></returns>
        public async Task<OperateStatus> SaveType(AgileConfig input)
        {
            OperateStatus operateStatus = new OperateStatus();
            AgileConfig agileConfig = await FindAsync(f => f.ConfigId == input.ConfigId);
            agileConfig.Name = input.Name;
            agileConfig.UseType = input.UseType;
            agileConfig.TypeId = input.TypeId;
            agileConfig.OrderNo = input.OrderNo;
            agileConfig.Remark = input.Remark;
            operateStatus = await UpdateAsync(agileConfig);
            var allAgileConfig = await FindAllAsync(f => f.MenuId == agileConfig.MenuId);
            foreach (var item in allAgileConfig)
            {
                item.TypeId = input.TypeId;
                operateStatus = await UpdateAsync(item);
            }
            if (operateStatus.Code == ResultCode.Success)
            {
                operateStatus.Msg = "保存成功";
            }
            return operateStatus;
        }
        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<OperateStatus> SaveJson(AgileConfig input)
        {
            return await UpdateAsync(u => u.ConfigId == input.ConfigId, new { SaveJson = input.SaveJson, UpdateTime = DateTime.Now });
        }

        /// <summary>
        /// 发布
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<OperateStatus> PublicJson(AgileConfig input)
        {
            //生成文件
            FileUtil.WriteFile(ConfigurationUtil.GetUploadPath() + "/agile/" + input.ConfigId + ".txt", JsonConvert.SerializeObject(new
            {
                publicJson = input.PublicJson,
                columnJson = input.ColumnJson
            }));
            return await UpdateAsync(u => u.ConfigId == input.ConfigId, new { SaveJson = input.SaveJson, PublicJson = input.PublicJson, ColumnJson = input.ColumnJson, UpdateTime = DateTime.Now });
        }

        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="paging"></param>
        /// <returns></returns>
        public async Task<OperateStatus<PagedResults<AgileConfig>>> Find(AgileConfigFindInput paging)
        {
            return OperateStatus<PagedResults<AgileConfig>>.Success(await _agileConfigRepository.Find(paging));
        }

        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="paging"></param>
        /// <returns></returns>
        public async Task<OperateStatus<AgileConfig>> FindById(IdInput input)
        {
            return OperateStatus<AgileConfig>.Success(await FindAsync(f => f.ConfigId == input.Id));
        }

        /// <summary>
        /// 根据菜单获取
        /// </summary>
        /// <param name="paging"></param>
        /// <returns></returns>
        public async Task<OperateStatus<IEnumerable<AgileConfigFindByMenuIdOutput>>> FindByMenuId(AgileConfigFindByMenuIdInput input)
        {
            List<AgileConfigFindByMenuIdOutput> outputs = new List<AgileConfigFindByMenuIdOutput>();
            using (var fix = new SqlDatabaseFixture())
            {
                var agile = await fix.Db.AgileConfig.SetSelect(s => new { s.ConfigId, s.Name, s.ConfigType, s.UseType, s.TypeId }).FindAllAsync(f => f.MenuId == input.MenuId);
                if (input.ConfigType == 2)
                {
                    var menu = await fix.Db.SystemMenu.SetSelect(s => new { s.Icon, s.Theme }).FindAsync(f => f.MenuId == input.MenuId);
                    foreach (var item in agile.ToList().Where(w => w.ConfigType == 2))
                    {
                        AgileConfigFindByMenuIdOutput findByMenuIdOutput = new AgileConfigFindByMenuIdOutput()
                        {
                            ConfigId = item.ConfigId,
                            Name = item.Name,
                            Icon = menu.Icon,
                            Theme = menu.Theme,
                            UseType = item.UseType,
                            TypeId = item.TypeId
                        };

                        outputs.Add(findByMenuIdOutput);
                    }
                }
                if (input.ConfigType == 1)
                {
                    foreach (var item in agile.ToList().Where(w => w.ConfigType == 1))
                    {
                        AgileConfigFindByMenuIdOutput findByMenuIdOutput = new AgileConfigFindByMenuIdOutput()
                        {
                            ConfigId = item.ConfigId,
                            Name = item.Name,
                        };

                        outputs.Add(findByMenuIdOutput);
                    }
                }
            }
            return OperateStatus<IEnumerable<AgileConfigFindByMenuIdOutput>>.Success(outputs);
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<OperateStatus> Delete(IdInput<string> input)
        {
            foreach (var id in input.Id.Split(','))
            {
                var configId = Guid.Parse(id);
                await UpdateAsync(u => u.ConfigId == configId, new { IsDelete = true });
            }
            return OperateStatus.Success();
        }

        /// <summary>
        /// 获取基础配置信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<OperateStatus<IEnumerable<AgileConfigFindBaseOutput>>> FindBase(AgileConfigFindBaseInput input)
        {
            return OperateStatus<IEnumerable<AgileConfigFindBaseOutput>>.Success(await _agileConfigRepository.FindBase(input));
        }

        /// <summary>
        /// 获取表单字段,若为第三方则检测表名字段是否具有,若有则读取对于的表字段
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<OperateStatus<List<AgileConfigFindFormColumnsOutput>>> FindFormColumns(IdInput input)
        {
            List<AgileConfigFindFormColumnsOutput> outputs = new List<AgileConfigFindFormColumnsOutput>();
            var config = await FindAsync(f => f.ConfigId == input.Id);

            if (config.ColumnJson.IsNotNullOrEmpty())
            {
                var columns = config.ColumnJson.JsonStringToList<AgileConfigFindFormColumnsJsonOutput>();
                foreach (var item in columns)
                {
                    AgileConfigFindFormColumnsOutput formColumnsOutput = new AgileConfigFindFormColumnsOutput
                    {
                        Name = item.Model,
                        Description = item.Label,
                        Type = item.Type
                    };
                    outputs.Add(formColumnsOutput);
                }
                return OperateStatus<List<AgileConfigFindFormColumnsOutput>>.Success(outputs);
            }
            //是否具有表名
            if (config.DataFromName.IsNotNullOrEmpty())
            {
                var columns = await _agileDataBaseRepository.FindDataBaseColumns(new AgileDataBaseTableDto { Name = config.DataFromName });
                foreach (var item in columns)
                {
                    AgileConfigFindFormColumnsOutput formColumnsOutput = new AgileConfigFindFormColumnsOutput
                    {
                        Name = item.Name,
                        Description = item.Description,
                        Type = item.Type
                    };
                    outputs.Add(formColumnsOutput);
                }
            }
            return OperateStatus<List<AgileConfigFindFormColumnsOutput>>.Success(outputs);
        }
        #endregion
    }
}